package com.okex.open.api.customize.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.okex.open.api.customize.constant.ApiOkxConstant;
import com.okex.open.api.customize.enums.ApiOkxEnum;
import com.pig4cloud.pigx.common.customize.exception.ApiRequestException;
import com.pig4cloud.pigx.common.customize.exception.MqAckLogException;
import com.pig4cloud.pigx.strategy.enums.StrategyOrderContractEnum;
import com.pig4cloud.pigx.user.entity.UserApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 欧易api工具类
 *
 * @since 2022/11/30 17:57
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ApiOkxUtil {

    /**
     * 根据返回结果的状态码判断是否成功
     *
     * @param res 返回结果
     * @return {@link boolean}
     * @since 2022/11/30 18:01
     */
    public static boolean isSuccess(JSONObject res) throws ApiRequestException {
        return isSuccess(res, true);
    }

    /**
     * 根据返回结果的状态码判断是否成功
     *
     * @param res       返回结果
     * @param autoThrow 失败时是否直接抛出异常
     * @return {@link boolean}
     * @since 2022/11/30 18:01
     */
    public static boolean isSuccess(JSONObject res, boolean autoThrow) {
        String code = getResCode(res);
        boolean success = Objects.equals(code, ApiOkxConstant.SUCCESS_CODE);

        if (!success && autoThrow) {
            String msg = getResMsg(res);
            if (Strings.isBlank(msg)) {
                msg = "请求API接口失败，返回结果：" + JSON.toJSONString(res);
            }

            throw new MqAckLogException(msg);
        }

        return success;
    }

    /**
     * 获取ok返回结果中的code
     *
     * @param res 返回结果
     * @return {@link String}
     * @since 2023/2/3 09:49
     */
    public static String getResCode(JSONObject res) {
        String code = res.getString(ApiOkxConstant.CODE);
        if (Strings.isBlank(code)) {
            JSONArray data = res.getJSONArray(ApiOkxConstant.DATA);
            if (!Objects.isNull(data) && !data.isEmpty()) {
                JSONObject firstData = data.getJSONObject(0);
                code = firstData.getString(ApiOkxConstant.S_CODE);
            }
        }

        return code;
    }

    /**
     * 获取ok返回结果中的msg
     *
     * @param res 返回结果
     * @return {@link String}
     * @since 2023/2/3 09:49
     */
    public static String getResMsg(JSONObject res) {
        String msg = res.getString(ApiOkxConstant.MSG);
        if (Strings.isBlank(msg)) {
            JSONArray data = res.getJSONArray(ApiOkxConstant.DATA);
            if (!Objects.isNull(data) && !data.isEmpty()) {
                JSONObject firstData = data.getJSONObject(0);
                msg = firstData.getString(ApiOkxConstant.S_MSG);
            }
        }

        return msg;
    }

    /**
     * 根据操作类型、方向获取ok应传入的订单side值（等于我方的操作类型）
     * <p> 开多：买入开多（side 填写 buy； posSide 填写 long ）
     * <p> 开空：卖出开空（side 填写 sell； posSide 填写 short ）
     * <p> 平多：卖出平多（side 填写 sell； posSide 填写 long ）
     * <p> 平空：买入平空（side 填写 buy； posSide 填写 short ）
     *
     * @param side          方向（0做多、1做空）
     * @param operationType 操作类型（0开仓、1平仓）
     * @return {@link String}
     * @since 2022/11/30 18:01
     */
    public static String getSide(String side, String operationType) {
        if (Objects.equals(ApiOkxEnum.Side.LONG.getValue(), side)) {
            if (Objects.equals(StrategyOrderContractEnum.OperationType.OPEN.getValue(), operationType)) {
                return ApiOkxEnum.OperationType.BUY.getName();
            } else {
                return ApiOkxEnum.OperationType.SELL.getName();
            }

        } else {
            if (Objects.equals(StrategyOrderContractEnum.OperationType.OPEN.getValue(), operationType)) {
                return ApiOkxEnum.OperationType.SELL.getName();
            } else {
                return ApiOkxEnum.OperationType.BUY.getName();
            }
        }
    }

    /**
     * 检查用户ApiKey
     *
     * @param api 用户ApiKey
     * @since 2022/12/3 10:40
     */
    public void checkUserApi(UserApi api) throws ApiRequestException {

        if (Objects.isNull(api)) {
            throw new ApiRequestException("用户ApiKey信息为空");
        }
        if (Strings.isBlank(api.getApiKey())) {
            throw new ApiRequestException("用户ApiKey信息中ApiKey为空");
        }
        if (Strings.isBlank(api.getSecretKey())) {
            throw new ApiRequestException("用户ApiKey信息中SecretKey为空");
        }
        if (Strings.isBlank(api.getPassword())) {
            throw new ApiRequestException("用户ApiKey信息中Password为空");
        }
    }

}
